package com.orm.mybatis.redis.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.orm.mybatis.redis.entity.User;
import com.orm.mybatis.redis.mapper.UserMapper1;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.List;

@RestController
public class RedisController {

    @Resource
    private UserMapper1 userMapper1;

    //@Cacheable用于查询和添加缓存，第一次查询的时候返回该方法返回值，并向 Redis 服务器保存数据。
    //以后调用该方法先从 Redis 中查是否有数据，如果有直接返回 Redis 缓存的数据，而不执行方法里的代码。如果没有则正常执行方法体中的代码。
    //value 或 cacheNames 属性做键，key 属性则可以看作为 value 的子键， 一个 value 可以有多个 key 组成不同值存在 Redis 服务器。
    //验证了下，value 和 cacheNames 的作用是一样的，都是标识主键。两个属性不能同时定义，只能定义一个，否则会报错。
    @Cacheable(value = "user",key = "#id")
    @GetMapping(value = "/get/user")
    public User getUser(@RequestParam Long id){
        User user = userMapper1.selectUserById(id);
        System.out.println("走了DB查询"+id);
        return user;
    }


    @Cacheable(value = "user",key = "'getUserList'")
    @GetMapping(value = "/get/userList")
    public List<User> getUserList(){
        List<User> userList = userMapper1.selectAllUser();
        System.out.println("走了DB查询userList");
        return userList;
    }


    //使用CachePut注解，该方法每次都会执行，会清除对应的key值得缓存(或者更新)，
    //分为以下两种情况：
    //
    //如果返回值null，下次进行该key值查询时，还会查一次数据库，此时相当于@CacheEvict注解;
    //
    //如果返回值不为null，此时会进行该key值缓存的更新，更新缓存值为返回的数据；
    @CachePut(value = "user",key = "#user.id")
    @CacheEvict(value = "user", allEntries = true,beforeInvocation = true)
    @PostMapping(value = "/update/user",produces = "application/json;charset=UTF-8")
    public User updateUser(@RequestBody User user){
        userMapper1.updateUserById(user);
        User user1 = userMapper1.selectUserById(user.getId());
        return user1;
        //此时进行id为1数据更新操作,返回值不为null；
        //如果下次进行/get/user id为1的数据查询，发现此时id为1缓存被更新为更新的数据，且没有进行DB查询操作;
    }

    //在需要删除缓存的方法上加注解：@CacheEvict(cacheNames = "prodcut", key = "#id")，执行完这个方法之后会将 Redis 中对应的记录删除。
//    @CacheEvict(value = "user",key = "#id")
    @CacheEvict(value = "user",allEntries = true)
    @GetMapping(value = "/cancel/user")
    public void updateUser(@RequestParam Long id){

    }

}
